﻿<#
.SYNOPSIS  
    Retracts and uninstalls all solutions.  
.DESCRIPTION  
    
.NOTES
    Sometime solutions fail to uninstall.  Review log files for errors.
.LINK  
    http://7up.codeplex.com 
#>

Write-Host ("   Removing solutions ({0})..." -f [DateTime]::Now.ToString())

#add SharePoint snap in
if ((Get-PSSnapin -Name  Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null) 
{ 
    Add-PsSnapin  Microsoft.SharePoint.PowerShell 
}

<#
 Runs pending timer jobs
#>
function Execute-AdminServiceJobs()
{
	Stop-Service -Name "SPAdminV4" -Confirm:$false
	Start-SPAdminJob -Confirm:$false
	Start-Service -Name "SPAdminV4" -Confirm:$false
}

<#
 Uninstalls the specified solution from the specified applications
#>
function Uninstall-Solution([string]$name, [string[]]$webApps = @())
{
    $solution = Get-SPSolution $name -ErrorAction SilentlyContinue
    
	# if solution installed
    if ($solution -ne $null) 
	{
		# if solution deployed, retract
        if ($solution.Deployed) 
		{
			# if deployed to web applications, retract from each
            if ($solution.ContainsWebApplicationResource) 
			{
			    if ($webApps -eq $null -or $webApps.Length -eq 0) 
				{
					Write-Warning "      The solution $name contains web application resources but no web applications were specified to retract from."
				}
				else 
				{
					foreach($webApp in $webApps)
					{
						Write-Host "      Retracting solution $name from $webApp..." -NoNewline
                		$solution | Uninstall-SPSolution -WebApplication $webApp -Confirm:$false
						
						Execute-AdminServiceJobs
						
						# block until the solution is no longer deployed
						do 
						{ 
							Start-Sleep 2
							$retryCount++
							Write-Host "." -NoNewLine 
							if($retryCount -gt 60)
							{
								Write-Host ""
								Write-Error "         Timeout retracting solution $name to $webApp"
								break
							} 
						} while ((Get-SPSolution $name).JobExists)
						
						Write-Host ""
						$solution = (Get-SPSolution $name)
						if($solution.LastOperationResult -ne " RetractionSucceeded")
						{
							Write-Error $solution.LastOperationDetails
						}
					}
				}
            } 
			else # globally deployed, retract
			{
				Write-Host "      Retracting solution $name..." -NoNewline
                $solution | Uninstall-SPSolution -Confirm:$false
            }
			
            Execute-AdminServiceJobs    
        
            # block until the solution is no longer deployed
			do 
			{ 
				Start-Sleep 2
				$retryCount++
				Write-Host "." -NoNewLine 
				if($retryCount -gt 60)
				{
					Write-Host ""
					Write-Error "         Timeout retracting solution $name to $webApp"
					break
				} 
			} while ((Get-SPSolution $name).JobExists)
			
			Write-Host ""
			$solution = (Get-SPSolution $name)
			if($solution.LastOperationResult -ne " RetractionSucceeded")
			{
				Write-Error $solution.LastOperationDetails
			}
        }
        
        # remove the solution
        Write-Host "      Removing solution $name..."
        Get-SPSolution $name | Remove-SPSolution -Confirm:$false
    }
}

#get config
$config = [xml](Get-Content Upgrade.xml)

foreach($solution in $config.Settings.Solutions.Solution)
{
	if($solution -ne $null)
	{
		Uninstall-Solution $solution.Name $solution.WebApplications.WebApplication
	}
}